package com.manolovn.trianglify;

import com.manolovn.trianglify.generator.color.ColorGenerator;
import com.manolovn.trianglify.generator.point.PointGenerator;
import com.manolovn.trianglify.util.ClassUtil;
import com.manolovn.trianglify.util.LogUtil;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.app.Context;

/**
 * Trianglify view
 */
public class TrianglifyView extends Component implements Component.EstimateSizeListener,
         Component.DrawTask{
    private static final String TAG = TrianglifyView.class.getSimpleName();
    private static final String CELL_SIZE = "cellSize";
    private static final String VARIANCE = "variance";
    private static final String BLEED_X = "bleedX";
    private static final String BLEED_Y = "bleedY";
    private static final String COLOR_GENERATOR = "colorGenerator";
    private static final String POINT_GENERATOR = "pointGenerator";

    private TrianglifyDrawable drawable;

    public TrianglifyView(Context context) {
        super(context);
        init(null);
    }

    public TrianglifyView(Context context, AttrSet attrs) {
        super(context, attrs);
        init(attrs);
        addDrawTask(this);
        setEstimateSizeListener(this);
    }

    public TrianglifyView(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
        addDrawTask(this);
        setEstimateSizeListener(this);
    }

    private void init(AttrSet attrs) {
        ColorGenerator colorGenerator = Default.colorGenerator;
        PointGenerator pointGenerator = Default.pointGenerator;
        int cellSize = Default.cellSize;
        int variance = Default.variance;
        int bleedX = Default.bleedX;
        int bleedY = Default.bleedY;

        if (attrs != null) {
                if(attrs.getAttr(CELL_SIZE).get().getIntegerValue() > 0) {
                    cellSize = attrs.getAttr(CELL_SIZE).isPresent()
                        ? attrs.getAttr(CELL_SIZE).get().getIntegerValue() : cellSize;
                }
                else {
                    cellSize = Default.cellSize;
                }

                if(attrs.getAttr(VARIANCE).get().getIntegerValue() > 0) {
                     variance = attrs.getAttr(VARIANCE).isPresent()
                        ? attrs.getAttr(VARIANCE).get().getIntegerValue() : variance;
                 }
                else {
                    variance = Default.variance;
                }

                if(attrs.getAttr(BLEED_X).get().getIntegerValue() > 0) {
                    bleedX = attrs.getAttr(BLEED_X).isPresent()
                            ? attrs.getAttr(BLEED_X).get().getIntegerValue() : bleedX;
                }
                else {
                    bleedX = Default.bleedX;
                }

                if(attrs.getAttr(BLEED_Y).get().getIntegerValue() > 0) {
                    bleedY = attrs.getAttr(BLEED_Y).isPresent()
                            ? attrs.getAttr(BLEED_Y).get().getIntegerValue() : bleedY;
                }
                else {
                    bleedY = Default.bleedY;
                }

                colorGenerator = attrs.getAttr(COLOR_GENERATOR).isPresent()
                        ? getColorGeneratorByName(attrs.getAttr(COLOR_GENERATOR).get().getStringValue())
                        : colorGenerator;

                pointGenerator = attrs.getAttr(POINT_GENERATOR).isPresent()
                        ? getPointGeneratorByName(attrs.getAttr(POINT_GENERATOR).get().getStringValue())
                        : pointGenerator;
        }

        drawable = new TrianglifyDrawable(bleedX, bleedY, cellSize, variance, colorGenerator,
                pointGenerator);

        setBackground(drawable);
    }

    @Override
    public boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
        setEstimatedSize(widthMeasureSpec, heightMeasureSpec);
        drawable.setBounds(0, 0, getEstimatedWidth(), getEstimatedHeight());
        return false;
    }

    public TrianglifyDrawable getDrawable() {
        return drawable;
    }

    private ColorGenerator getColorGeneratorByName(String className) {
        if (className == null || className.isEmpty()) {
            return null;
        }
        return ClassUtil.getClassByName(className, ColorGenerator.class);
    }

    private PointGenerator getPointGeneratorByName(String className) {
        if (className == null || className.isEmpty()) {
            return Default.pointGenerator;
        }
        return ClassUtil.getClassByName(className, PointGenerator.class);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        getDrawable().onBoundsChange(component.getWidth(), component.getHeight());
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            LogUtil.error(TAG, e.getMessage());
        }
        getDrawable().draw(canvas);
    }
}
